package org.jetnuke.modules.calendar;

import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.dao.CalendarEventDAO;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.modules.calendar.utils.CalendarUtils;

public class YearCalendar implements IAction {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(YearCalendar.class);

	int year = 0;

	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - start"); //$NON-NLS-1$
		}

		if (ui == null || ui.getID() < 2)
			return null;
		// Locale locale=(Locale)vc.get("_locale");
		if (year == 0) {
			year = new GregorianCalendar().get(Calendar.YEAR);
		}
		CalendarUtils.putCommonObjects(vc);
		HashMap mp = new HashMap();
		CalendarEventDAO cedao = DataAccessDriver.getInst()
				.newCalendarEventDAO();
		List daysWithEvents = cedao.selectDaysWithEvents(ui.getID(), year);
		GregorianCalendar firstDay = new GregorianCalendar(year, 0, 1, 0, 0);
		firstDay.set(Calendar.SECOND, 0);
		firstDay.set(Calendar.MILLISECOND, 0);

		GregorianCalendar lastDay = new GregorianCalendar(year + 1, 0, 1, 0, 0);
		lastDay.set(Calendar.SECOND, 0);
		lastDay.set(Calendar.MILLISECOND, 0);
		List recurringDaysEvents = new ArrayList();
		List recurringEvents = cedao.selectPeriodRecurringEvents(ui.getID(),
				firstDay, lastDay);
		// recurringEvents are sorted.
		for (int iMonth = 0; iMonth < 12; iMonth++) {
			GregorianCalendar gc = getFirstDayOnCalendar(year, iMonth);
			GregorianCalendar dt = gc;
			HashMap days = new HashMap();
			for (int i = 0; i < 6; i++) {
				for (int j = 0; j < 7; j++) {
					GregorianCalendar tmp = new GregorianCalendar();
					tmp.setTime(dt.getTime());
					if (tmp.get(Calendar.MONTH) == iMonth) {
						if (!CalendarUtils.getActiveRecurringEvent(
								recurringEvents, tmp).isEmpty()) {
							if (Collections.binarySearch(daysWithEvents, tmp) < 0) {
								recurringDaysEvents.add(tmp);
							}

						}
					}
					days.put(new Integer(i + j * 7), tmp);
					dt.add(java.util.Calendar.DATE, 1);
				}
			}
			mp.put(new Integer(iMonth), days);
		}
		vc.put("mpDays", mp);
		vc.put("year", new Integer(year));

		recurringDaysEvents.addAll(daysWithEvents);
		Collections.sort(recurringDaysEvents);
		vc.put("daysWithEvents", recurringDaysEvents);
		ActionForward returnActionForward = new ActionForward(op, info);
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - end"); //$NON-NLS-1$
		}
		return returnActionForward;
	}

	public void setYear(int year) {
		this.year = year;
	}

	private static GregorianCalendar getFirstDayOnCalendar(int year_, int month_) {
		if (logger.isDebugEnabled()) {
			logger.debug("getFirstDayOnCalendar(int, int) - start"); //$NON-NLS-1$
		}

		GregorianCalendar g = new GregorianCalendar(year_, month_, 1);
		int dow = g.get(java.util.Calendar.DAY_OF_WEEK);

		if (dow != 1)
			g.add(java.util.Calendar.DATE, ((dow - 1) * -1));

		if (logger.isDebugEnabled()) {
			logger.debug("getFirstDayOnCalendar(int, int) - end"); //$NON-NLS-1$
		}
		return g;
	}

}
